import { Session } from '../src/session';
import { ToolRegistry, Tool } from '../src/tools';
import { InMemoryMemoryStore } from '../src/memory';
import { NodeType } from '../src/types';

// Custom tool that simulates file editing
const editTool: Tool = {
  name: 'str-replace-editor',
  description: 'Edit files by replacing text',
  async run(input: any) {
    const { path, old_str, new_str } = input as { path: string; old_str: string; new_str: string };
    
    // Simulate file editing with some delay
    await new Promise(r => setTimeout(r, 50));
    
    return {
      success: true,
      path,
      changes: {
        linesAdded: new_str.split('\n').length,
        linesRemoved: old_str.split('\n').length,
        diff: `- ${old_str}\n+ ${new_str}`
      }
    };
  }
};

// Custom provider that demonstrates tool usage
class ToolDemoProvider {
  async *generate(req: any) {
    const now = Date.now();
    
    yield { type: NodeType.Thinking, ts: now, requestId: req.requestId };
    yield { type: NodeType.RawResponse, ts: now + 10, requestId: req.requestId, text: 'I\'ll help you edit that file. ' };
    
    // Emit tool usage
    yield { 
      type: NodeType.ToolUse, 
      ts: now + 20, 
      requestId: req.requestId, 
      tool: 'str-replace-editor',
      input: {
        path: 'example.ts',
        old_str: 'console.log("old");',
        new_str: 'console.log("new and improved");'
      }
    };
    
    yield { type: NodeType.RawResponse, ts: now + 30, requestId: req.requestId, text: 'File has been updated successfully!' };
    yield { type: NodeType.MainTextFinished, ts: now + 40, requestId: req.requestId };
  }
}

async function main() {
  console.log('🔧 Tool Execution Demo\n');

  const provider = new ToolDemoProvider();
  const tools = new ToolRegistry();
  const memories = new InMemoryMemoryStore();

  // Register our custom tool
  tools.register(editTool);

  const session = new Session({ 
    model: provider as any, 
    tools, 
    memories, 
    allowAutoTools: true 
  });

  console.log('📝 Requesting file edit...');
  const turnId = await session.send({ requestMessage: 'Please update the console.log in example.ts' });

  // Wait for processing
  await new Promise(r => setTimeout(r, 150));

  const turn = session.getTurn(turnId)!;
  console.log(`\n✅ Turn status: ${turn.status}`);
  console.log('📋 Execution trace:\n');

  turn.nodes.forEach((node, i) => {
    console.log(`${i + 1}. [${node.type}] @ ${new Date(node.ts).toISOString()}`);
    
    if (node.type === NodeType.ToolUse) {
      const toolNode = node as any;
      console.log(`   🔧 Tool: ${toolNode.tool}`);
      console.log(`   📥 Input:`, JSON.stringify(toolNode.input, null, 2));
      if (toolNode.result) {
        console.log(`   📤 Result:`, JSON.stringify(toolNode.result, null, 2));
      }
      if (toolNode.error) {
        console.log(`   ❌ Error: ${toolNode.error}`);
      }
    } else if (node.type === NodeType.RawResponse) {
      console.log(`   💬 "${(node as any).text}"`);
    }
    console.log('');
  });
}

main().catch(console.error);
